<?php

namespace app\common\library;

use app\common\model\Device;
use app\common\model\DeviceStatus;
use \PhpMqtt\Client\MqttClient;
use think\Db;
/**
 * 泡泡机设备socket交互接口
 */
class Socket
{

    protected $server   = 'd-paopao.bigchun.com';
    protected $port     = 28599;
    protected $username     = 'admin';
    protected $password     = 'paopaoji123';
    protected $clientId = '';
    protected $mqtt;
    protected $maxRetries = 3;
    protected $retryDelay = 2;
    public function __construct()
    {

        $this->clientId = "PPC001";
        $this->mqtt = new MqttClient($this->server, $this->port, $this->clientId);
        // 检查连接状态
        if ($this->mqtt->isConnected()) {
            echo $this->mqtt->getClientId();
        } else {
            $this->mqtt->connect();
        }
    


    }

    public function checkDbConnection()
    {
        $attempts = 0;
        while ($attempts < $this->maxRetries) {
            try {
                Db::execute('SELECT 1');
                return true;
            } catch (\Exception $e) {
                $attempts++;
                Db::close();
                if ($attempts >= $this->maxRetries) {
                    var_dump("数据库连接失败，已重试 {$attempts} 次: " . $e->getMessage());
                    return false;
                }
                sleep($this->retryDelay);
            }
        }
        return false;
    }

    /**
     * 订阅方法
     */
    public function subscribe()
    {

        //0 [信号强度(0-31)& 31&
        //1 ICCID& 898608162623D0048950&
        //2 网络模式(5),工作时间段& 5,8:30~23:0&
        //3 提示音间隔时间& 600&
        //4 音量& 30&
        //5 电压(mV)& 11760&
        //6 水位& 1&
        //7 车锁状态& 0&
        //8 LED2灯状态& 0&
        //9 LED1灯状态& 0&
        //10 泡泡电机状态& 0&
        //11 音乐状态& 0&
//        12LED2时间段& 18:0~23:0
//        13 LED1时间段& 18:0~23:0
        //14 提示音时间段,硬件版本& 18:0~23:0,ZT-PPJ-V8.1&
        //15 软件版本] Z5.20
        $clientId = 'admin';
        $mqtt = new MqttClient($this->server, $this->port, $clientId);
        $mqtt->connect();
        try {
            $mqtt->subscribe('ZHZN/#', function ($topic, $message) {
                // 检查数据库连接
                if (!$this->checkDbConnection()) {
                   var_dump("无法建立数据库连接，消息处理失败");
                }

                $device_status_model = new DeviceStatus();
                var_dump($message);
                $mesage_arr = json_decode($message,true);
                $m = $mesage_arr['m'];
                $m_arr = explode('&',$m);
//            {"c": 105, "mi": 190, "m": "31&898608162623D0048950&5,8:30~23:0&600&30&12060&1&0&1&0&0&0&18:0~23:0,ZT-PPJ-V8.1&Z5.20", "f": "868330079267466", "s": "", "t": "PPC001"}
                if ($mesage_arr['c'] == 105){
                    //心跳数据
                    $m_arr2 = explode(',',$m_arr[2]);
                    $m_arr14 = explode(',',$m_arr[14]);
                    $add_data = [
                        'signal_strength'=> $m_arr[0],
                        'iccid'=> $m_arr[1],
                        'work_time'=> end($m_arr2),
                        'prompt_interval_time'=> $m_arr[3],
                        'vol'=> $m_arr[4],
                        'voltage'=> $m_arr[5],
                        'water_level'=> $m_arr[6],
                        'car_lock'=>$m_arr[7] ,
                        'led2'=>$m_arr[8],
                        'led1'=> $m_arr[9],
                        'motor'=> $m_arr[10],
                        'music'=>$m_arr[11] ,
                        'led2_time'=> $m_arr[12],
                        'led1_time'=> $m_arr[13],
                        'reminder_time'=> $m_arr14[0],
                        'hardware_version'=>$m_arr14[1] ,
                        'software_version'=>$m_arr[15],
                    ];


                }elseif ($mesage_arr['c'] == 21){
                    //支付应答
                    $start_arr = explode(',',$m_arr[0]);
                    $add_data = [
                        'start_status'=>1,
                        'start_mode'=>$start_arr[1],
                        'start_time'=>time(),
                        'stop_time'=>0,
                        'start_time_int'=>$m_arr[1],
                    ];
                }elseif ($mesage_arr['c'] == 23){
                    //支付应答
                    $start_arr = explode(',',$m_arr[0]);
                    $add_data = [
                        'start_mode'=>$start_arr[1],
                        'start_status'=>1,
                        'stop_time'=>0,
                    ];
                }elseif ($mesage_arr['c'] == 20){
                    //泡泡机启动结束
                    $add_data = [
                        'stop_time'=>time(),
                    ];
                }elseif ($mesage_arr['c'] == 151){
                    $add_data = [
                        'led1'=>$m,
                    ];
                }elseif ($mesage_arr['c'] == 153){
                    $add_data = [
                        'music'=>$m,
                    ];
                }elseif ($mesage_arr['c'] == 155){
                    $add_data = [
                        'motor'=>$m,
                    ];
                }elseif ($mesage_arr['c'] == 131){
                    $m_music = explode(',',$m);
                    $add_data = [
                        'vol'=>$m_music[1],
                    ];
                }elseif ($mesage_arr['c'] == 103){
                    $device_model = new Device();
                    $device_info = $device_model->where('name',trim($mesage_arr['f']))->find();
                    $device_type = 'offline';
                    $device_data = [
                        'type'=>$device_type,
                        'panttime'=>time(),
                    ];
                    if ($device_info){
                        $device_model->where('name',trim($mesage_arr['f']))->update($device_data);
                    }else{
                        $device_data['name'] = trim($mesage_arr['f']);
                        $device_model->insert($device_data);
                    }
                }else{
                    echo $message.'---没有处理的数据';
                }
                if (isset($add_data) && $add_data){
                    $add_data['updatetime'] = time();
                    //设备绑定
                    if ($mesage_arr['c'] == 105){
                        $device_model = new Device();
                        $device_info = $device_model->where('name',trim($mesage_arr['f']))->find();
                        $device_type = 'online';
                        $yj_status = 0;
                        if ($add_data['water_level'] == 0 && $add_data['voltage'] < 9600){
                            $yj_status = 3;
                        }elseif($add_data['water_level'] == 0){
                            $yj_status = 1;
                        }elseif ($add_data['voltage'] < 9600){
                            $yj_status = 2;
                        }
                        $ele =($add_data['voltage'] - 9600)/2500*100;
                        if ($ele > 100){
                            $ele = 100;
                        }elseif ($ele <0){
                            $ele = 0;
                        }
                        $device_data = [
                            'type'=>$device_type,
                            'yj_status'=>$yj_status,
                            'panttime'=>time(),
                            'ele'=>$ele
                        ];


                        if ($device_info){
                            $device_model->where('name',trim($mesage_arr['f']))->update($device_data);
                        }else{
                            $device_data['name'] = trim($mesage_arr['f']);
                            $device_model->insert($device_data);
                        }
                    }

                    $device_status_info = $device_status_model->where('device_name',trim($mesage_arr['f']))->find();
                    if ($device_status_info){
                        $device_status_model->where('device_name',trim($mesage_arr['f']))->update($add_data);
                    }else{
                        $add_data['device_name'] = trim($mesage_arr['f']);
                        $device_status_model->insert($add_data);
                    }


                    echo '设备数据插入成功'.date('Y-m-d H:i:s').'<br>';
                }

            }, 0);
            $mqtt->loop(true);
            $mqtt->disconnect();
        }catch (\Exception $exception){
            $mqtt->loop(true);
            $mqtt->disconnect();
            echo $exception->getMessage();
        }

    }

    /*
     * 扫码运行指令-启动泡泡机
     * @param array $start_list 设备数组[["device_name"=>33434243333333,"type"=>1,"time"=>600]] type默认1  出泡泡时间time
     * @return
     */
    public function startDev($start_list)
    {

        if (empty($start_list)){
            return $this->result('数据不能为空',400);
        }

        foreach ($start_list as $k=>$v){
            $device_name = $v['device_name'];
            if ($device_name == ''){
                return $this->result('设备不能为空',400);
            }
            $type = $v['type'] ?? 1;
            $time = $v['time'] ?? 600;
            $data_arr = [
                "c"=> 22,
                "f"=> $this->clientId,
                "t"=> $device_name,
                "m"=> "10,$type&$time",
                "s"=> "11112",
                "mi"=> 2
            ];
            $json_data = json_encode($data_arr);
            $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        }
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    /*
    * 开关电机
    * @param $device_name 设备唯一ID
    * @param $m 控制电机状态=0时关闭泡泡电机，=1时开启泡泡电机  默认0
    */
    public function stopDev($device_name,$m=0)
    {
        if ($device_name == ''){
            return $this->result('设备不能为空');
        }
        $data_arr = [
            "c"=> 154,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $m,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    /*
     * 音量调节
     * @param int $vol 音量0-30范围
     * @param $device_name 设备唯一ID
     */
    public function volDev($device_name,$vol=30)
    {
        if ($device_name == ''){
            return $this->result('设备不能为空');
        }
        $data_arr = [
            "c"=> 130,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $vol,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    /*
     * 灯光控制
     * @param $switch =0时关闭LED，=1时开启LED
     */
    public function ledDev($device_name,$switch=1)
    {
        if ($device_name == ''){
            return $this->result('设备不能为空');
        }
        $data_arr = [
            "c"=> 150,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $switch,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    /*
     * 引流
     * @param $device_name 设备唯一ID
     * @param $paopao_interval_time 泡泡间隔时间默认600秒
     * @param $paopao_time 吹泡泡时长默认10秒
     */
    public function beckon($device_name,$paopao_interval_time=600,$paopao_time=10)
    {
        if ($device_name == ''){
            $this->result('设备不能为空');
        }
        $m = "$paopao_interval_time&$paopao_time,$paopao_interval_time&$paopao_time";
        $data_arr = [
            "c"=> 120,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $m,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    /*
     * 灯工作时间段设置
     * @param $device_name 设备唯一ID
     * @param $worker_time 设置工作时间段
     */
    public function ledTime($device_name,$worker_time='18:00~23:00')
    {
        if ($device_name == ''){
            $this->result('设备不能为空');
        }
        $data_arr = [
            "c"=> 124,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $worker_time,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    /*
    * 音乐时间段设置
    * @param $device_name 设备唯一ID
    * @param $worker_time 设置工作时间段  18 00~18 00前后一致就是关闭
    */
    public function musicTime($device_name,$worker_time='18:00~23:00')
    {
        if ($device_name == ''){
            $this->result('设备不能为空');
        }
        $data_arr = [
            "c"=> 126,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $worker_time,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    /*
    * 音乐开关
    * @param $device_name 设备唯一ID
    * @param $m  =0时关闭音乐，=1时开启音乐
    */
    public function musicDev($device_name,$m=0)
    {
        if ($device_name == ''){
            $this->result('设备不能为空');
        }
        $data_arr = [
            "c"=> 152,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $m,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    /*
     * 待机引流
     * @param $device_name 设备唯一ID
     * @param $worker_time 设置工作时间段
     * @param $paopao_interval_time 泡泡间隔时间默认600秒
     * @param $paopao_time 吹泡泡时长默认10秒
     */
    public function awaitBeckon($device_name,$worker_time='9:00~23:00',$paopao_interval_time=600,$paopao_time=10)
    {
        if ($device_name == ''){
            $this->result('设备不能为空');
        }
        $m = "$paopao_interval_time&$paopao_time,$paopao_interval_time&$paopao_time";
        $data_arr = [
            "c"=> 120,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $m,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        $data_arr = [
            "c"=> 116,
            "f"=> $this->clientId,
            "t"=> $device_name,
            "m"=> $worker_time,
            "s"=> "11112",
            "mi"=> 2
        ];
        $json_data = json_encode($data_arr);
        $this->mqtt->publish("ZHZN/$device_name",  $json_data, 0);
        // $this->mqtt->disconnect();
        return $this->result('发送成功');
    }

    protected function result($msg, $code = 0, $data = null)
    {
        $result = [
            'code' => $code,
            'msg'  => $msg,
            'data' => $data,
        ];
        return $result;
        }
}
